package com.cgy.utils.jmx.system.mem;

import com.cgy.utils.jmx.IJvmInfoFactory;
import com.cgy.utils.jmx.jvm.utils.SizeUtils;
import com.cgy.utils.jmx.system.hardware.Hardware;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil;

import java.util.Arrays;
import java.util.List;

import static com.cgy.utils.jmx.RateHelper.rate;

/**
 * @author CH
 */
public class MemSystemFactory extends IJvmInfoFactory {

    @Override
    public void status() {
        OperatingSystem os = Hardware.OPERATING_SYSTEM;

        long memoryTotal = Hardware.GLOBAL_MEMORY.getTotal();
        long swapUsed = Hardware.GLOBAL_MEMORY.getSwapUsed();
        long swapTotal = Hardware.GLOBAL_MEMORY.getSwapTotal();
        long available = Hardware.GLOBAL_MEMORY.getAvailable();

        put("mem.sys.total.long", memoryTotal, "系统最大内存");
        put("mem.sys.total.String", SizeUtils.getDataSize(memoryTotal), "系统最大内存");

        put("mem.sys.used.long", memoryTotal - available, "系统已用内存");
        put("mem.sys.used.String", SizeUtils.getDataSize(memoryTotal - available), "系统已用内存");
        put("mem.sys.used.rate", rate(memoryTotal - available, memoryTotal), "系统已用内存");

        put("mem.sys.swap.used.long", swapUsed, "系统swap使用内存");
        put("mem.sys.swap.used.String", SizeUtils.getDataSize(swapUsed), "系统swap使用内存");

        put("mem.sys.swap.total.long", swapTotal, "系统swap最大内存");
        put("mem.sys.swap.total.String", SizeUtils.getDataSize(swapTotal), "系统swap最大内存");

        put("mem.sys.ava.total.long", available, "系统avail最大内存");
        put("mem.sys.ava.total.String", SizeUtils.getDataSize(available), "系统可用内存");
        put("mem.sys.ava.total.rate", rate(available, memoryTotal), "系统可用内存");

        System.out.println("Processes: " + os.getProcessCount() + ", Threads: " + os.getThreadCount());
        // Sort by highest CPU
        List<OSProcess> procs = Arrays.asList(os.getProcesses(5, OperatingSystem.ProcessSort.CPU));

        System.out.println("   PID  %CPU %MEM       VSZ       RSS Name");
        for (int i = 0; i < procs.size() && i < 5; i++) {
            OSProcess p = procs.get(i);
            System.out.format(" %5d %5.1f %4.1f %9s %9s %s%n", p.getProcessID(),
                    100d * (p.getKernelTime() + p.getUserTime()) / p.getUpTime(),
                    100d * p.getResidentSetSize() / memoryTotal, FormatUtil.formatBytes(p.getVirtualSize()),
                    FormatUtil.formatBytes(p.getResidentSetSize()), p.getName());
        }
    }
}
